package com.woniuxy.orderserver.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.common.dto.SkuDto;
import com.woniuxy.common.dto.UserDto;
import com.woniuxy.common.utils.UserUtil;
import com.woniuxy.orderserver.feign.ConsumeFeign;
import com.woniuxy.orderserver.feign.ProductFeign;
import com.woniuxy.orderserver.pojo.FinanceOrder;
import com.woniuxy.orderserver.pojo.FinanceOrderDetail;
import com.woniuxy.orderserver.service.FinanceOrderDetailService;
import com.woniuxy.orderserver.service.FinanceOrderService;
import com.woniuxy.orderserver.mapper.FinanceOrderMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;

import java.math.BigDecimal;

import static com.woniuxy.common.constant.FinanceConstant.Exchange.ORDER_EXCHANGE;
import static com.woniuxy.common.constant.FinanceConstant.RabbitMq.*;
import static com.woniuxy.common.utils.UserUtil.getUser;

/**
* @author 76169
* @description 针对表【finance_order】的数据库操作Service实现
* @createDate 2024-12-17 19:03:25
*/
@Slf4j
@Service
public class FinanceOrderServiceImpl extends ServiceImpl<FinanceOrderMapper, FinanceOrder>
    implements FinanceOrderService{


    @Autowired
    private HttpServletRequest request;

    @Autowired
    private ProductFeign productFeign;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ConsumeFeign consumeFeign;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public String addCart(Integer skuId) {
        try {
            //1.获取用户信息
            UserDto userDto = getUser(request);
            String userId = userDto.getId().toString();

            //如果购物车没有物品则创建，否则添加数量
            Object json = redisTemplate.opsForHash().get("CART:" + userId, skuId.toString());
            SkuDto sku=null;
            if(ObjectUtil.isNull(json)){
                // 2.获取商品信息
                sku = productFeign.queryByid(skuId);
                sku.setCount(1);
            }else {
                sku = JSON.parseObject(json.toString(), SkuDto.class);
                //用于判断后加字段，向下兼容
                if(ObjectUtil.isNull(sku.getCount())){
                    sku.setCount(1);
                }else {
                    sku.setCount(sku.getCount()+1);
                }

            }

            // 3.添加到购物车
            redisTemplate.opsForHash().put("CART:"+userId+"",skuId.toString(), JSON.toJSONString(sku));
        } catch (Exception e) {
            log.error("skuId:{} addCart is error:{}",skuId,e);
            return "添加失败";
        }
        return "添加成功";
    }

    @Value("${snowflake.workerId}")
    private Long workId;
    @Value("${snowflake.dataCenterId}")
    private Long dataCenterId;

    @Autowired
    private FinanceOrderDetailService financeOrderDetailService;

    @Override
//    @GlobalTransactional(rollbackFor = Exception.class)//全局事务
    public String addOrder(Integer skuId) {
        // 订单数据(主表和明细表)
        // 订单id：雪花id
        long orderId = IdUtil.getSnowflake(workId, dataCenterId).nextId();

        // 用户id：从token中获取
        UserDto user = getUser(request);

        //商品
        SkuDto skuDto = productFeign.queryByid(skuId);
        saveOrder(orderId, user, skuDto);

        saveDetail(skuId, orderId, skuDto);

        // 调用服务：商品减库存
        Boolean a = productFeign.updateSku(Long.valueOf(skuId));

        // 调用服务：金融（生产分期数据） userId,orderId,购买金额
        Boolean b = consumeFeign.payPlan(user.getId(), orderId, BigDecimal.valueOf(skuDto.getFinanceSkuPrice()));
        if(a && b){
            return "下单成功";
        }
        return "下单失败";
    }

    private void saveDetail(Integer skuId, long orderId, SkuDto skuDto) {
        FinanceOrderDetail financeOrderDetail = new FinanceOrderDetail();
        financeOrderDetail.setFinanceOrderId(orderId);
        financeOrderDetail.setFinanceSkuId(Long.valueOf(skuId));
        financeOrderDetail.setFinanceNum(1);
        financeOrderDetail.setFinancePrice(BigDecimal.valueOf(skuDto.getFinanceSkuPrice()));
        financeOrderDetailService.save(financeOrderDetail);
    }

    private void saveOrder(long orderId, UserDto user, SkuDto skuDto) {
        FinanceOrder order = new FinanceOrder();
        order.setId(orderId);
        order.setFinanceUserId(user.getId());
        order.setFinanceUser(user.getFinanceAccount());
        order.setFinancePayment(1);
        order.setFinanceAddrId(1l);
        order.setFinanceAddr("江凌");
        order.setFinanceSumPrice(skuDto.getFinanceSkuPrice());
        save(order);
    }

    @Override
    public void addOrder(UserDto user, Long orderId, SkuDto sku) {
        //保存订单
        saveOrder(orderId, user, sku);
        //保存订单明细
        saveDetail(sku.getId().intValue(), orderId, sku);
    }

    @Override
    public void rollbackOrder(String orderId) {
        //如果未支付则订单回滚并且发送消息给商品和金融服务
        FinanceOrder order = getById(orderId);
        if(ObjectUtil.isNull(order)){
            //订单不存在，直接返回
            log.warn("订单不存在，订单id:{}",order);
            return;
        }

        //0:已删除 1.待支付 2.待发货 3.已发货 4.订单已完成 5.已取消
        if(order.getFinanceState() !=1){
            log.warn("订单已取消，无需回滚，订单id:{},订单状态id:{}",orderId,order.getFinanceState());
            return;
        }
        //修改订单装填为0：订单表示删除
        order.setFinanceState(0);
        updateById(order);

        //发送消息给商品服务
        Long skuId = financeOrderDetailService.lambdaQuery().eq(FinanceOrderDetail::getFinanceOrderId, orderId).one().getFinanceSkuId();
        rabbitTemplate.convertAndSend(ORDER_EXCHANGE,"rollback.sku.routing.key",skuId.toString());

        //发送消息给金融服务
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(SUM_PRICE,order.getFinanceSumPrice());
        jsonObject.put(ORDER_ID,orderId);
        jsonObject.put(USER_ID,order.getFinanceUserId());
        rabbitTemplate.convertAndSend(ORDER_EXCHANGE,"rollback.consume.routing.key",jsonObject.toString());
    }


}




